package jehc.cloud.oauth.client.timer;
import cn.hutool.core.collection.CollectionUtil;
import jehc.cloud.common.util.RestTemplateUtil;
import jehc.cloud.common.util.StringUtil;
import jehc.cloud.common.util.date.DateUtil;
import jehc.cloud.oauth.client.constant.Constant;
import jehc.cloud.oauth.client.service.PushService;
import jehc.cloud.oauth.client.timer.task.ExpireTokenTask;
import jehc.cloud.oauth.client.util.HeartbeatAttributesUtil;
import jehc.cloud.oauth.client.vo.Token;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ForkJoinPool;
/**
 * @Desc Push 更新在线Token有效期 客户端信息至授权中心
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Component
@Slf4j
public class ExpireTokenPushScheduled {
    @Autowired
    PushService pushService;

    @Autowired
    RestTemplateUtil restTemplateUtil;

    @Autowired
    HeartbeatAttributesUtil heartbeatAttributesUtil;

    @Scheduled(cron="*/30 * * * * *")
    public void execute() {
        try {
            if(heartbeatAttributesUtil.isConnected()){
                initForkJoinPool();
            }else{
                log.error("无法连接授权中心...");
            }
        }catch (Exception e){
            log.error("推送Token有效期至授权中心异常：{}",e);
        }
    }

    /**
     * 筛选需要更新的Token
     * @return
     */
    public  Map<String,Token> filterKeepAliveToken(){
        Map<String,Token> tokenMap = pushService.getTokenData();

        Map<String,Token> dataMap = new ConcurrentHashMap<>();
        if(CollectionUtil.isEmpty(tokenMap)){
            log.info("没有可推送的Token信息");
            return null;
        }

        Iterator<Map.Entry<String, Token>> entries = tokenMap.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<String, Token> entry = entries.next();
            Long t = 0L;
             if(null != entry.getValue()){
                if(!StringUtil.isEmpty(entry.getValue().getUpdateTimes())){
                    try {
                        Long time =  DateUtil.dateToStamp(entry.getValue().getUpdateTimes());
                        Long time2 = new Date().getTime();
                        t = time2-time;
                    }catch (Exception e){
                        log.error("上次更新时间与当前时间比较异常：{}",e);
                    }
                }
                if((entry.getValue().getKeepAlive() == false)||(t != 0L && t < Constant.KEEP_ALIVE_TIME)){
                    continue;
                }
                 dataMap.put(entry.getKey(),entry.getValue());
            }
        }
       return dataMap;
    }

    /**
     *
     */
    public void initForkJoinPool(){
        long millis1 = System.currentTimeMillis();
        int size = Runtime.getRuntime().availableProcessors();//获取本系统的有效线程数，设置线程池为有效线程的两倍。
        ForkJoinPool forkJoinPool = new ForkJoinPool(size*2);
        try {
            Map<String,Token> tokenMap = filterKeepAliveToken();
            if(CollectionUtil.isEmpty(tokenMap)){
                return;
            }
            ExpireTokenTask initTask = new ExpireTokenTask(tokenMap,Constant.EXPIRE_TOKEN_GROUP_NUMBER,restTemplateUtil);
            //方法一 同步
            Integer result = forkJoinPool.invoke(initTask);
//                //线程阻塞，等待所有任务完成
//                forkJoinPool.awaitTermination(forkJoinTimeOut, TimeUnit.SECONDS);


//                //方法二 异步
//                ForkJoinTask forkJoinTask = forkJoinPool.submit(initTask);
//                result = new Integer(forkJoinTask.get());


//                //方法三 异步
//                Future<Integer> futureResult = forkJoinPool.submit(initTask);
//                result = futureResult.get();
            long millis2 =  System.currentTimeMillis();
            log.info("更新Token有效期耗时:"+(millis2-millis1)+"毫秒，共更新："+result+"条记录！");
        }catch (Exception e){
            if(null != forkJoinPool){
                forkJoinPool.shutdown();
            }
        }finally {
            if(null != forkJoinPool){
                forkJoinPool.shutdown();
            }
        }
    }
}
